package com.guchenbo.example.sasl;

import javax.security.auth.callback.*;
import javax.security.sasl.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class SaslDemo {
    public static void main(String[] args) throws SaslException {
        String mechanism = "DIGEST-MD5"; // 选择SASL机制
        String[] mechanisms = { "DIGEST-MD5" }; // 选择SASL机制
        String protocol = "example"; // 使用的协议
        String serverName = "myServer"; // 服务器名
        String authorizationId = "ttest"; // 服务器名
        Map<String, String> props = new HashMap<>();
        // 客户端提供的用户名和密码
        String username = "myUser";
        String password = "myPassword";
        ServerCallbackHandler serverCallbackHandler = new ServerCallbackHandler();
        ClientCallbackHandler clientCallbackHandler = new ClientCallbackHandler();
        SaslServer saslServer = Sasl.createSaslServer(mechanism, protocol, serverName, props, serverCallbackHandler);
        SaslClient saslClient = Sasl.createSaslClient(mechanisms, authorizationId, protocol, serverName, props,
                        clientCallbackHandler);


        byte[] challenge;
        byte[] response;

        // 初始response and challenge
        challenge = saslServer.evaluateResponse(new byte[0]);
        // client evaluateChallenge 之后，会进入client 的 callback
        response = saslClient.evaluateChallenge(challenge);

        // server evaluateResponse 之后，会进入server 的 callback
        challenge = saslServer.evaluateResponse(response);
        response = saslClient.evaluateChallenge(challenge);

        System.out.println(saslServer.isComplete());
        System.out.println(saslClient.isComplete());
    }
    public static class ServerCallbackHandler implements CallbackHandler {
        @Override
        public void handle(Callback[] cbs) throws IOException, UnsupportedCallbackException {
            for (Callback cb : cbs) {
                if (cb instanceof AuthorizeCallback) {
                    AuthorizeCallback ac = (AuthorizeCallback) cb;
                    //Perform application-specific authorization action
                    ac.setAuthorized(true);
                } else if (cb instanceof NameCallback) {
                    NameCallback nc = (NameCallback) cb;
                    //Collect username in application-specific manner
                    nc.setName("username2");
                } else if (cb instanceof PasswordCallback) {
                    PasswordCallback pc = (PasswordCallback) cb;
                    //Collect password in application-specific manner
                    pc.setPassword("password".toCharArray());
                } else if (cb instanceof RealmCallback) {
                    RealmCallback rc = (RealmCallback) cb;
                    //Collect realm data in application-specific manner
                    rc.setText("myServer");
                }
            }
            System.out.println(cbs.length);
        }
    }
    public static class ClientCallbackHandler implements CallbackHandler {
        @Override
        public void handle(Callback[] cbs) throws IOException, UnsupportedCallbackException {
            for (Callback cb : cbs) {
                if (cb instanceof NameCallback) {
                    NameCallback nc = (NameCallback) cb;
                    //Collect username in application-specific manner
                    nc.setName("username");
                } else if (cb instanceof PasswordCallback) {
                    PasswordCallback pc = (PasswordCallback) cb;
                    //Collect password in application-specific manner
                    pc.setPassword("password".toCharArray());
                } else if (cb instanceof RealmCallback) {
                    RealmCallback rc = (RealmCallback) cb;
                    //Collect realm data in application-specific manner
                    rc.setText("myServer");
                }
            }
            System.out.println(cbs.length);

        }
    }
}
